/*
 *  StudentAIControllerExample.cpp
 *  Pirates2011
 *
 *  Created by Alan Dorin on 14/03/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#include "StudentAIControllerExample.h"

#include <iostream>

// This function is called once per time step to update your ship by the external framework
// You will need to write it to return what you want your ship to do after each time step.
// Available actions for each ship to choose from once per time step are ONLY:

// Globals::actionMoveAhead - move the ship one square ahead in the direction it is facing
// Globals::actionTurnLeft - turn the ship to the left by 90 degrees
// Globals::actionTurnRight - turn the ship to the right by 90 degrees
// Globals::actionCollectGold - attempt to collect gold from the current location
// Globals::actionFireCannonAhead - fire the cannon straight ahead 
// Globals::actionPass - do nothing (wait out this time step)

Globals::ShipAction StudentAIControllerExample::computeNextAction(void)
{
	// In here you put your own function calls.
	// Or, instead, try one of these example routines provided for you...
	
	// return randomAction( );
	return avoidRocksAndShootAction();
	// return straightAheadAction();
}

// Not a good strategy, but a very simple one... just keep sailing straight ahead
Globals::ShipAction StudentAIControllerExample::straightAheadAction(void)
{
	return Globals::actionMoveAhead;
}

// Here is a randomly handled ship...
Globals::ShipAction StudentAIControllerExample::randomAction(void)
{
	Globals::ShipAction action = Globals::actionPass;
	
	// get a random number
	long randNum = (random() % 6);

	// then work out what action we want to do next
	switch (randNum)
	{
		case 0:
			action = Globals::actionMoveAhead;
		break;
		case 1:
			action = Globals::actionTurnRight;
		break;
		case 2:
			action = Globals::actionTurnLeft;
		break;
		case 3:
			action = Globals::actionCollectGold;
		break;
		case 4:
			action = Globals::actionFireCannonAhead;
		break;
		case 5:
			action = Globals::actionPass;
		break;
		
		default:
			std::cerr << "ERROR: StudentAIControllerExample::computeNextAction() selected invalid action!";
	}
	return action;

}

// Here is a ship that looks in front of it for rocks or other ships.
// If the space in front is clear it moves ahead.
// If there is a rock ahead it turns in a random direction.
// If there is a ship ahead it fires its cannon at it.
Globals::ShipAction StudentAIControllerExample::avoidRocksAndShootAction(void)
{
	Globals::ShipAction action = Globals::actionPass;
	
	long aheadX = 0, aheadY = 0;
	
	// If there is a marker here for gold and we didn't collect gold at the previous time step
	// Try to collect gold now. Since gold markers are left in place even if their gold is collected
	// a ship should keep track of which markers it has searched to avoid wasting time searching
	// a marker that has already been cleared.
	if (isGoldMarkerHere() && (getMyLastAction() != Globals::actionCollectGold))
	{ action = Globals::actionCollectGold; }
	
	else
	{
		// Work out which direction the ship is facing
		Globals::NeighbourDirection aheadDirection = getShipAheadDirection();
		
		// Now work out which square is the one in the location ahead of us based on the direction we are facing.
		switch (aheadDirection)
		{
			case Globals::neighbourUp:
				aheadX = 0;			// if the ship is facing up, moving ahead does not involve moving along the x-axis
				aheadY = 1;			// moving ahead increases the Y coordinate
			break;
			case Globals::neighbourRight:
				aheadX = 1;			// moving ahead increases the X coordinate
				aheadY = 0;			// if the ship is facing right, moving ahead does not involve moving along the y-axis
			break;
			case Globals::neighbourDown:
				aheadX = 0;			// if the ship is facing down, moving ahead does not involve moving along the x-axis
				aheadY = -1;		// moving ahead decreases the Y coordinate
			break;
			case Globals::neighbourLeft:
				aheadX = -1;		// moving ahead decreases the X coordinate
				aheadY = 0;			// if the ship is facing left, moving ahead does not involve moving along the y-axis
			break;
			default:
				std::cerr << "ERROR: StudentAIControllerExample::rockAvoidAction() selected invalid direction!";
		}
		
		if (isRockAt(aheadX, aheadY) == true)				// if there is a rock ahead
		{
			long randNum = (random() % 2);					// choose a random direction to turn
			switch (randNum)
			{
				case 0:
					action = Globals::actionTurnRight;
				break;
				default:
					action = Globals::actionTurnLeft;
				break;
			}
		}
		
		else if (isShipAt(aheadX, aheadY) == true)			// if there is a ship ahead
		{
			action = Globals::actionFireCannonAhead;		// fire the cannon at it
		}
		
		else
		{ action = Globals::actionMoveAhead; }				// otherwise move ahead
	}
	
	setMyLastAction(action);								// store the action so next time we can remember what we did
	return action;
}

// A couple of helper routines for you to use to keep track of the last action
// your ship made...

void StudentAIControllerExample::setMyLastAction(Globals::ShipAction action)
{
	myLastAction = action;
}

Globals::ShipAction StudentAIControllerExample::getMyLastAction(void)
{
	return myLastAction;
}
